<template>
  <div>
    <el-form :label-width="labelWidth" class="BBForm">
      <el-row>
        <template v-for="item in formItems" :key="item.label" >
          <el-col v-bind="colLayout" >
            <el-form-item :label="item.label" :style="formStyle" v-if="!item.isHidden">
              <template
                v-if="item.type === 'input' || item.type === 'password'"
              >
                <el-input
                  type="text"
                  width="100%"
                  :placeholder="item.placeholder"
                  :show-password="item.type === 'password'"
                  :rules="item.rules"
                  v-model="formData[`${item.filed}`]"
                />
              </template>
              <template v-else-if="item.type === 'select'">
                <el-select
                  style="width: 100%"
                  :placeholder="item.placeholder"
                  v-model="formData[`${item.filed}`]"
                >
                  <el-option
                    v-for="option in item.options"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                    :rules="option.rules"
                  />
                </el-select>
              </template>
              <template v-else-if="item.type === 'datepicker'">
                <el-date-picker
                  type="daterange"
                  range-separator="To"
                  start-placeholder="Start date"
                  end-placeholder="End date"
                  :rules="item.rules"
                  v-model="formData[`${item.filed}`]"
                />
              </template>
            </el-form-item>
          </el-col>
        </template>
      </el-row>
    </el-form>
    <div class="footer">
      <slot name="footer"></slot>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, watch } from "vue";
import { IFormItem } from "@/base-ui/form/types";
import { PropType } from "vue";
export default defineComponent({
  name: "Form",
  props: {
    formItems: {
      //IFormItem 后面要加数组的符号
      type: Array as PropType<IFormItem[]>,
      // 默认值如果为数组或者对象类型的话，要写成函数类型
      default: () => [],
    },
    //宽度的设置
    labelWidth: {
      type: String,
      default: "100px",
    },
    //样式设置
    formStyle: {
      type: Object,
      default: () => ({ padding: "0px 40px" }),
    },
    //布局设置
    colLayout: {
      type: Object,
      default: () => ({
        //根据屏幕分辨率的大小，设置span值的大小
        xl: 8,
        lg: 8,
        md: 12,
        sm: 24,
        xs: 24,
      }),
    },

    //这是使用 : 来进行组件间数据绑定，违背了单向数据流的原则
    // formData:{
    //   type:Object,
    //   required:true
    // }

    // 使用 v-model 来进行绑定
    modelValue: {
      type: Object,
      required: true,
    },
  },
  emits: ["update:modelValue"],
  setup(props, { emit }) {
    //这是使用 第二种方法，通过 v-model 加上computed
    // const formData = computed({
    //   get: () => props.modelValue,
    //   set: (newValue) => {
    //     // console.log('1111');
    //     // 问题: 并没有执行 emit 里面的代码
    //     emit("update:modelValue", newValue);
    //   },
    // });

    // 第三种方法
    const formData = ref({ ...props.modelValue });

    // watch(()=> props.modelValue,() => {
    //   formData.value = { ...props.modelValue }
    // })

    watch(
      formData,
      (newValue) => {
        emit("update:modelValue", newValue);
      },
      { deep: true }
    );

    return {
      formData,
    };
  },
});
</script>

<style lang='less' scoped>
 .BBForm {
  color: #fff;
  padding-top: 15px;
  ::v-deep(.el-form-item__label){
    font-size: 18px;
    color: #000;
  }
}
.footer {
    text-align: center;
    margin:14px 85px 14px 0
    
  }
</style>